package cn.dapeng.thread.delayedQueue;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @BelongProject study
 * @BelongPackage cn.dapeng.thread.delayedQueue
 * @Description 同步阻塞延时对列实现
 * @ClassName MyDelayQueueWithSyn
 * @Author xupenghong
 * @Date 2024/8/28 14:23
 * @Version 1.0.0
 */
public class MyDelayQueueWithSyn<E extends MyDelayed> extends MyAbstractQueue<E> {

    private final Condition fullCondition = getLock().newCondition();
    private final Condition emptyCondition = getLock().newCondition();

    public MyDelayQueueWithSyn(int capacity) {
        super(capacity);
    }

    @Override
    public boolean add(E e) throws Exception {
        final ReentrantLock lock = getLock();
        lock.lock();
        try {
            while (getSize() == getCapacity()) {
                fullCondition.await();
            }
            getArray().addToTail(e);
            emptyCondition.signalAll();
        } finally {
            lock.unlock();
        }
        return true;
    }

    @Override
    public E take() throws Exception {
        final ReentrantLock lock = getLock();
        lock.lock();
        try {
            while (getSize() == 0) {
                emptyCondition.await();
            }
            fullCondition.signalAll();
            for (; ; ) {
                if (peek().getDelay(TimeUnit.NANOSECONDS) <= 0) {
                    return getArray().removeFromTail();
                }
            }
        } finally {
            lock.unlock();
        }
    }


}